﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Issues.VillageNeedsToolsIssueBehavior
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Issues
{
  public class VillageNeedsToolsIssueBehavior : CampaignBehaviorBase
  {
    private const IssueBase.IssueFrequency VillageNeedsToolsIssueFrequency = IssueBase.IssueFrequency.VeryCommon;

    public override void RegisterEvents()
    {
      CampaignEvents.OnCheckForIssueEvent.AddNonSerializedListener((object) this, new Action<Hero>(this.OnCheckForIssue));
    }

    private void OnCheckForIssue(Hero hero)
    {
      ItemObject tools = DefaultItems.Tools;
      if (this.ConditionsHold(hero, tools))
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(new PotentialIssueData.StartIssueDelegate(this.OnStartIssue), typeof (VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue), IssueBase.IssueFrequency.VeryCommon, (object) tools));
      else
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(typeof (VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue), IssueBase.IssueFrequency.VeryCommon));
    }

    private bool ConditionsHold(Hero issueGiver, ItemObject item)
    {
      Settlement currentSettlement = issueGiver.CurrentSettlement;
      return issueGiver.IsHeadman && currentSettlement != null && currentSettlement.IsVillage && currentSettlement.Village.GetProsperityLevel() < SettlementComponent.ProsperityLevel.Mid && currentSettlement.Village.VillageType.Productions.Count > 0 && currentSettlement.Village.VillageType.Productions.All<(ItemObject, float)>((Func<(ItemObject, float), bool>) (x => !x.Item1.IsAnimal)) && currentSettlement.ItemRoster.GetItemNumber(item) == 0;
    }

    private IssueBase OnStartIssue(in PotentialIssueData pid, Hero issueOwner)
    {
      return (IssueBase) new VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue(issueOwner, (ItemObject) pid.RelatedObject);
    }

    public override void SyncData(IDataStore dataStore)
    {
    }

    public class VillageNeedsToolsIssue : IssueBase
    {
      private const int TimeLimit = 30;
      private const int TroopTierForAlternativeSolution = 2;
      public const int PowerRewardForQuestGiverOnSuccess = 10;
      private const int RelationWithIssueOwnerRewardOnSuccess = 5;
      private const int VillageHeartChangeOnSuccess = 50;
      private const int RequiredSkillValueForAlternativeSolution = 120;
      [SaveableField(10)]
      private readonly ItemObject _requestedItem;
      [SaveableField(20)]
      private readonly ItemObject _exchangeItem;
      [SaveableField(30)]
      private readonly int _numberOfExchangeItem;
      [SaveableField(40)]
      private readonly int _numberOfRequestedItem;
      [SaveableField(50)]
      private readonly int _payment;

      internal static void AutoGeneratedStaticCollectObjectsVillageNeedsToolsIssue(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._requestedItem);
        collectedObjects.Add((object) this._exchangeItem);
      }

      internal static object AutoGeneratedGetMemberValue_requestedItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue) o)._requestedItem;
      }

      internal static object AutoGeneratedGetMemberValue_exchangeItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue) o)._exchangeItem;
      }

      internal static object AutoGeneratedGetMemberValue_numberOfExchangeItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue) o)._numberOfExchangeItem;
      }

      internal static object AutoGeneratedGetMemberValue_numberOfRequestedItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue) o)._numberOfRequestedItem;
      }

      internal static object AutoGeneratedGetMemberValue_payment(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue) o)._payment;
      }

      public override IssueBase.AlternativeSolutionScaleFlag AlternativeSolutionScaleFlags
      {
        get => IssueBase.AlternativeSolutionScaleFlag.Duration;
      }

      protected override int RewardGold
      {
        get
        {
          return 500 + this._numberOfRequestedItem * (int) ((double) (this.IssueSettlement.SettlementComponent.GetItemPrice(this._requestedItem) + this._requestedItem.Value) / 2.0);
        }
      }

      private int CostOfToolsForAlternativeSolution
      {
        get
        {
          return (int) ((double) (this._requestedItem.Value * this._numberOfRequestedItem) * 0.699999988079071);
        }
      }

      protected override int CompanionSkillRewardXP
      {
        get => 500 + (int) (700.0 * (double) this.IssueDifficultyMultiplier);
      }

      public override TextObject Title
      {
        get
        {
          TextObject title = new TextObject("{=gnuojd9u}{VILLAGE} Needs Tools");
          title.SetTextVariable("VILLAGE", this.IssueOwner.CurrentSettlement.Name);
          return title;
        }
      }

      public override TextObject Description
      {
        get
        {
          return new TextObject("{=Td2RGRBn}Headman in the village requested tools to increase production.");
        }
      }

      public override TextObject IssueBriefByIssueGiver
      {
        get
        {
          return new TextObject("{=BGJpwxvm}We do have some problems. [ib:demure][if:convo_dismayed] A sickness passed through here last month. Praise the Heavens, only a few people died, but many were weakened and we couldn't get much work done. Now we need to hire some laborers from nearby settlements to make up the shortfall, but we don't have the tools for them. We're in a bit of a rush - do you think you could find tools for us?");
        }
      }

      public override TextObject IssueAcceptByPlayer
      {
        get => new TextObject("{=3EL0wY1h}Tell me about the details.");
      }

      public override TextObject IssueQuestSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver;
          if (this._exchangeItem == null)
          {
            explanationByIssueGiver = new TextObject("{=daXZlOBi}We need {REQUESTED_ITEM_COUNT} {.%}{?(REQUESTED_ITEM_COUNT > 1)}{PLURAL(REQUESTED_ITEM)}{?}{REQUESTED_ITEM}{\\?}{.%} in {NUMBER_OF_DAYS} days. We can offer {PAYMENT}{GOLD_ICON} for the tools and your services. What do you say?");
            explanationByIssueGiver.SetTextVariable("PAYMENT", this._payment);
          }
          else
          {
            explanationByIssueGiver = new TextObject("{=uwmfgcM3}We need {REQUESTED_ITEM_COUNT} {.%}{?(REQUESTED_ITEM_COUNT > 1)}{PLURAL(REQUESTED_ITEM)}{?}{REQUESTED_ITEM}{\\?}{.%} in {NUMBER_OF_DAYS} days. The village is short on denars so we can make the payment in kind - with {?NUMBER_OF_EXCHANGE_ITEM > 1}{NUMBER_OF_EXCHANGE_ITEM} {._}{PLURAL(EXCHANGE_ITEM)}{?}one {._}{EXCHANGE_ITEM}{\\?}. What do you say?");
            explanationByIssueGiver.SetTextVariable("EXCHANGE_ITEM", this._exchangeItem.Name);
            explanationByIssueGiver.SetTextVariable("NUMBER_OF_EXCHANGE_ITEM", this._numberOfExchangeItem);
          }
          explanationByIssueGiver.SetTextVariable("REQUESTED_ITEM", this._requestedItem.Name);
          explanationByIssueGiver.SetTextVariable("REQUESTED_ITEM_COUNT", this._numberOfRequestedItem);
          explanationByIssueGiver.SetTextVariable("NUMBER_OF_DAYS", 30);
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssuePlayerResponseAfterAlternativeExplanation
      {
        get => new TextObject("{=Tp4X51vX}Maybe my men can handle this for you.");
      }

      public override TextObject IssueAlternativeSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver = new TextObject("{=8llksa4h}If so, you'll need a man with good understanding of trade. Also you will need at least {NUMBER_OF_TROOPS} fighting men to protect the goods while taking them to market and back. Your companion will also probably need around {GOLD_COST}{GOLD_ICON} in order to buy the tools.[if:convo_confused_normal]");
          explanationByIssueGiver.SetTextVariable("NUMBER_OF_TROOPS", this.GetTotalAlternativeSolutionNeededMenCount());
          explanationByIssueGiver.SetTextVariable("GOLD_COST", this.CostOfToolsForAlternativeSolution);
          explanationByIssueGiver.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssueQuestSolutionAcceptByPlayer
      {
        get => new TextObject("{=ggGmjgIS}I think I can handle this myself.");
      }

      public override TextObject IssueAlternativeSolutionAcceptByPlayer
      {
        get => new TextObject("{=5aDpzB1F}My men will deliver your goods on time don't worry.");
      }

      public override TextObject IssueDiscussAlternativeSolution
      {
        get
        {
          return new TextObject("{=bkZOcbGu}Your men are still getting us the tools. I ask for your patience. We very much appreciate this.");
        }
      }

      public override bool IsThereAlternativeSolution => true;

      public override bool IsThereLordSolution => false;

      protected override int AlternativeSolutionBaseDurationInDaysInternal
      {
        get => 4 + MathF.Ceiling(5f * this.IssueDifficultyMultiplier);
      }

      public override int AlternativeSolutionBaseNeededMenCount
      {
        get => 2 + MathF.Ceiling(4f * this.IssueDifficultyMultiplier);
      }

      public override TextObject IssueAlternativeSolutionResponseByIssueGiver
      {
        get
        {
          return new TextObject("{=JxUrkzd1}Thank you. I hope your men can get us the tools on time. Good luck.[ib:demure][if:convo_astonished]");
        }
      }

      protected override TextObject AlternativeSolutionStartLog
      {
        get
        {
          TextObject parent = new TextObject("{=qycE7IO0}{QUEST_GIVER.LINK} told you that {?QUEST_GIVER.GENDER}she{?}he{\\?} needs {._}{ITEM} for {?QUEST_GIVER.GENDER}her{?}his{\\?} village. {?QUEST_GIVER.GENDER}She{?}He{\\?} offers you {REWARD_GOLD}{GOLD_ICON} for the delivery of the tools. You asked your companion {COMPANION.LINK} and {NEEDED_MEN_COUNT} of your men to deliver {NUMBER_OF_ITEM} {?NUMBER_OF_ITEM>1}units{?}unit{\\?} of {._}{ITEM} to {QUEST_GIVER.LINK}. They will rejoin your party in {ALTERNATIVE_SOLUTION_DURATION} days.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.IssueOwner.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("COMPANION", this.AlternativeSolutionHero.CharacterObject, parent);
          parent.SetTextVariable("ITEM", this._requestedItem.Name);
          parent.SetTextVariable("NUMBER_OF_ITEM", this._numberOfRequestedItem);
          parent.SetTextVariable("REWARD_GOLD", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          parent.SetTextVariable("NEEDED_MEN_COUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          parent.SetTextVariable("ALTERNATIVE_SOLUTION_DURATION", this.GetTotalAlternativeSolutionDurationInDays());
          return parent;
        }
      }

      public override TextObject IssueAlternativeSolutionSuccessLog
      {
        get
        {
          TextObject parent = new TextObject("{=W0w0Eunx}Your companion {COMPANION.LINK} has delivered {ISSUE_GIVER.LINK}'s goods as you promised.");
          StringHelpers.SetCharacterProperties("ISSUE_GIVER", this.IssueOwner.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("COMPANION", this.AlternativeSolutionHero.CharacterObject, parent);
          return parent;
        }
      }

      public VillageNeedsToolsIssue(Hero issueOwner, ItemObject requestedItem)
        : base(issueOwner, CampaignTime.DaysFromNow(30f))
      {
        this._requestedItem = requestedItem;
        int itemPrice = issueOwner.CurrentSettlement.SettlementComponent.GetItemPrice(this._requestedItem);
        this._numberOfRequestedItem = MathF.Round((float) (int) (2500.0 / (double) this._requestedItem.Value) * this.IssueDifficultyMultiplier);
        int num = 500 + this._numberOfRequestedItem * (int) ((double) (itemPrice + this._requestedItem.Value) / 2.0);
        if ((double) issueOwner.CurrentSettlement.Village.Hearth < 300.0)
        {
          this._exchangeItem = issueOwner.CurrentSettlement.Village.VillageType.PrimaryProduction;
          this._numberOfExchangeItem = MathF.Ceiling((float) num * 0.7f / (float) this._exchangeItem.Value);
        }
        else
        {
          this._payment = num;
          this._numberOfExchangeItem = 0;
          this._exchangeItem = (ItemObject) null;
        }
      }

      protected override float GetIssueEffectAmountInternal(IssueEffect issueEffect)
      {
        return issueEffect == DefaultIssueEffects.VillageHearth ? -0.2f : 0.0f;
      }

      public override (SkillObject, int) GetAlternativeSolutionSkill(Hero hero)
      {
        return (hero.GetSkillValue(DefaultSkills.Engineering) >= hero.GetSkillValue(DefaultSkills.Crafting) ? DefaultSkills.Engineering : DefaultSkills.Crafting, 120);
      }

      protected override void OnGameLoad()
      {
      }

      protected override void HourlyTick()
      {
      }

      protected override QuestBase GenerateIssueQuest(string questId)
      {
        return (QuestBase) new VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest(questId, this.IssueOwner, this._requestedItem, this._numberOfRequestedItem, this._exchangeItem, this._numberOfExchangeItem, this._payment, CampaignTime.DaysFromNow(30f));
      }

      public override IssueBase.IssueFrequency GetFrequency()
      {
        return IssueBase.IssueFrequency.VeryCommon;
      }

      protected override bool CanPlayerTakeQuestConditions(
        Hero issueGiver,
        out IssueBase.PreconditionFlags flag,
        out Hero relationHero,
        out SkillObject skill)
      {
        bool questConditions = (double) issueGiver.GetRelationWithPlayer() >= -10.0 && !issueGiver.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction);
        flag = questConditions ? IssueBase.PreconditionFlags.None : (!issueGiver.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction) ? IssueBase.PreconditionFlags.Relation : IssueBase.PreconditionFlags.AtWar);
        relationHero = issueGiver;
        skill = (SkillObject) null;
        return questConditions;
      }

      public override bool IssueStayAliveConditions()
      {
        return this.IssueOwner.CurrentSettlement.ItemRoster.GetItemNumber(this._requestedItem) == 0 && !this.IssueOwner.CurrentSettlement.IsRaided && !this.IssueOwner.CurrentSettlement.IsUnderRaid;
      }

      protected override void CompleteIssueWithTimedOutConsequences()
      {
      }

      public override void AlternativeSolutionStartConsequence()
      {
        GiveGoldAction.ApplyForCharacterToParty(Hero.MainHero, (PartyBase) null, this.CostOfToolsForAlternativeSolution);
      }

      public override bool DoTroopsSatisfyAlternativeSolution(
        TroopRoster troopRoster,
        out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(troopRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      public override bool IsTroopTypeNeededByAlternativeSolution(CharacterObject character)
      {
        return character.Tier >= 2;
      }

      public override bool AlternativeSolutionCondition(out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(MobileParty.MainParty.MemberRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2) && QuestHelper.CheckGoldForAlternativeSolution(this.CostOfToolsForAlternativeSolution, ref explanation);
      }

      protected override void AlternativeSolutionEndWithSuccessConsequence()
      {
        VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest.GiveTradeOrExchangeRewardToMainParty(this.IssueOwner, this._payment, this._exchangeItem, this._numberOfExchangeItem);
        ChangeRelationAction.ApplyPlayerRelation(this.IssueOwner, 5);
        this.IssueOwner.AddPower(10f);
        this.IssueOwner.CurrentSettlement.Village.Hearth += 50f;
      }
    }

    public class VillageNeedsToolsIssueQuest : QuestBase
    {
      private const int VillageHeartChangeOnExchangeSuccess = 40;
      private const int VillageHeartChangeOnTradeSuccess = 20;
      private const int TraitChangeOnSuccess = 30;
      private const int RelationChangeWithQuestGiverOnExchangeSuccess = 7;
      private const int RelationChangeWithNotablesOnExchangeSuccess = 2;
      private const int RelationChangeWithQuestGiverOnTradeSuccess = 5;
      private const int RelationChangeWithQuestGiverOnFail = -5;
      private const int QuestGiverPowerChangeOnFail = -10;
      private const int VillageHeartChangeOnFail = -30;
      [SaveableField(10)]
      private readonly ItemObject _requestedTradeGood;
      [SaveableField(20)]
      private readonly int _numberOfRequestedGood;
      [SaveableField(30)]
      private readonly ItemObject _exchangeItem;
      [SaveableField(40)]
      private readonly int _numberOfExchangeItem;
      [SaveableField(50)]
      private JournalLog _numberOfToolsLog;

      internal static void AutoGeneratedStaticCollectObjectsVillageNeedsToolsIssueQuest(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._requestedTradeGood);
        collectedObjects.Add((object) this._exchangeItem);
        collectedObjects.Add((object) this._numberOfToolsLog);
      }

      internal static object AutoGeneratedGetMemberValue_requestedTradeGood(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest) o)._requestedTradeGood;
      }

      internal static object AutoGeneratedGetMemberValue_numberOfRequestedGood(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest) o)._numberOfRequestedGood;
      }

      internal static object AutoGeneratedGetMemberValue_exchangeItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest) o)._exchangeItem;
      }

      internal static object AutoGeneratedGetMemberValue_numberOfExchangeItem(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest) o)._numberOfExchangeItem;
      }

      internal static object AutoGeneratedGetMemberValue_numberOfToolsLog(object o)
      {
        return (object) ((VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest) o)._numberOfToolsLog;
      }

      public override TextObject Title
      {
        get
        {
          TextObject title = new TextObject("{=gnuojd9u}{VILLAGE} Needs Tools");
          title.SetTextVariable("VILLAGE", this.QuestGiver.CurrentSettlement.Name);
          return title;
        }
      }

      public override bool IsRemainingTimeHidden => false;

      private TextObject QuestStartedLog
      {
        get
        {
          TextObject parent = new TextObject("{=BOp61V4A}{QUEST_GIVER.LINK} told you that {?QUEST_GIVER.GENDER}she{?}he{\\?} needs {._}{REQUIRED_ITEM} for {?QUEST_GIVER.GENDER}her{?}his{\\?} village. {?QUEST_GIVER.GENDER}She{?}He{\\?} asked you to bring {ITEM_COUNT} {.%}{?(ITEM_COUNT > 1)}{PLURAL(REQUIRED_ITEM)}{?}{REQUIRED_ITEM}{\\?}{.%}  to {?QUEST_GIVER.GENDER}her{?}him{\\?}. {PAYMENT_DESCRIPTION}");
          parent.SetTextVariable("REQUIRED_ITEM", this._requestedTradeGood.Name);
          parent.SetTextVariable("ITEM_COUNT", this._numberOfRequestedGood);
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          TextObject textObject;
          if (this._exchangeItem == null)
          {
            textObject = new TextObject("{=ZOTBiLiS}{?QUEST_GIVER.GENDER}She{?}He{\\?} will pay you {PAYMENT}{GOLD_ICON} when the task is done.");
            textObject.SetTextVariable("PAYMENT", this.RewardGold);
            textObject.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          }
          else
          {
            textObject = new TextObject("{=eQzskygV}{?QUEST_GIVER.GENDER}She{?}He{\\?} will make payment as {EXCHANGE_ITEM_COUNT} {?EXCHANGE_ITEM_COUNT>1}units{?}unit{\\?} of {._}{EXCHANGE_ITEM} when the task is done.");
            textObject.SetTextVariable("EXCHANGE_ITEM", this._exchangeItem.Name);
            textObject.SetTextVariable("EXCHANGE_ITEM_COUNT", this._numberOfExchangeItem);
          }
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, textObject);
          parent.SetTextVariable("PAYMENT_DESCRIPTION", textObject);
          return parent;
        }
      }

      private TextObject WarDeclaredQuestCancelLog
      {
        get
        {
          TextObject parent = new TextObject("{=PakhagOy}Your clan is now at war with {QUEST_GIVER.LINK}'s lord. Your agreement with {QUEST_GIVER.LINK} was canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject PlayerDeclaredWarQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=bqeWVVEE}Your actions have started a war with {QUEST_GIVER.LINK}'s faction. {?QUEST_GIVER.GENDER}She{?}He{\\?} cancels your agreement and the quest is a failure.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject VillageRaidedQuestCancelLog
      {
        get
        {
          TextObject parent = new TextObject("{=9zJNjWes}{SETTLEMENT} was raided. Your agreement with {QUEST_GIVER.LINK} was canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("SETTLEMENT", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
          return parent;
        }
      }

      private TextObject QuestTimeOutFailLog
      {
        get
        {
          TextObject parent = new TextObject("{=jXTshvhV}You couldn't fully bring {ITEM} to {?QUEST_GIVER.GENDER}her{?}him{\\?} on time.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("ITEM", this._requestedTradeGood.Name);
          return parent;
        }
      }

      private TextObject QuestSuccessLog
      {
        get
        {
          TextObject parent = new TextObject("{=ytqqEyFw}You brought {NUMBER_OF_ITEM} {?NUMBER_OF_ITEM>1}units{?}unit{\\?} of {ITEM} to {?QUEST_GIVER.GENDER}her{?}him{\\?} as promised.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("ITEM", this._requestedTradeGood.Name);
          parent.SetTextVariable("NUMBER_OF_ITEM", this._numberOfRequestedGood);
          return parent;
        }
      }

      public VillageNeedsToolsIssueQuest(
        string questId,
        Hero questGiver,
        ItemObject requestedItem,
        int numberOfRequestedGood,
        ItemObject exchangeItem,
        int numberOfExchangeItem,
        int payment,
        CampaignTime duration)
        : base(questId, questGiver, duration, payment)
      {
        this._requestedTradeGood = requestedItem;
        this._numberOfRequestedGood = numberOfRequestedGood;
        this._exchangeItem = exchangeItem;
        this._numberOfExchangeItem = numberOfExchangeItem;
        this.SetDialogs();
        this.InitializeQuestOnCreation();
      }

      protected override void SetDialogs()
      {
        this.OfferDialogFlow = DialogFlow.CreateDialogFlow("issue_classic_quest_start").NpcLine(new TextObject("{=ELxhTMuy}Excellent. But please hurry - we need to put the men we hired to work right away. Good luck.")).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).Consequence((ConversationSentence.OnConsequenceDelegate) (() =>
        {
          this.StartQuest();
          TextObject taskName = new TextObject("{=M8PXWpyV}Collected {ITEM}");
          taskName.SetTextVariable("ITEM", this._requestedTradeGood.Name);
          this._numberOfToolsLog = this.AddDiscreteLog(this.QuestStartedLog, taskName, 0, this._numberOfRequestedGood);
          this.UpdateToolsAmount();
        })).CloseDialog();
        this.DiscussDialogFlow = DialogFlow.CreateDialogFlow("quest_discuss").NpcLine(new TextObject("{=dJVjbgyu}Any news about our tools {?PLAYER.GENDER}madame{?}sir{\\?}?")).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).BeginPlayerOptions().PlayerOption(new TextObject("{=yvXNvh2B}Yes, I brought your tools.")).Condition(new ConversationSentence.OnConditionDelegate(this.PlayerHasTools)).NpcLine(new TextObject("{=yF3cBat5}Thank you {?PLAYER.GENDER}madame{?}sir{\\?}. Here is what we promised.")).Consequence(new ConversationSentence.OnConsequenceDelegate(this.FinishQuestSuccess1)).CloseDialog().PlayerOption(new TextObject("{=ULWYVuVw}I'm still looking for your goods.")).NpcLine(new TextObject("{=tkaEZNpB}Of course. But… please hurry, {?PLAYER.GENDER}madame{?}sir{\\?}. We can't afford to pay the hired men to sit around. We don't have much money to spare, {?PLAYER.GENDER}madame{?}sir{\\?}.")).CloseDialog().EndPlayerOptions();
      }

      private bool PlayerHasTools()
      {
        return this.GetCurrentToolsAmountInPlayerRoster() >= this._numberOfRequestedGood;
      }

      protected override void HourlyTick()
      {
      }

      protected override void RegisterEvents()
      {
        CampaignEvents.WarDeclared.AddNonSerializedListener((object) this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
        CampaignEvents.OnClanChangedKingdomEvent.AddNonSerializedListener((object) this, new Action<Clan, Kingdom, Kingdom, ChangeKingdomAction.ChangeKingdomActionDetail, bool>(this.OnClanChangedKingdom));
        CampaignEvents.RaidCompletedEvent.AddNonSerializedListener((object) this, new Action<BattleSideEnum, RaidEventComponent>(this.RaidCompleted));
        CampaignEvents.PlayerInventoryExchangeEvent.AddNonSerializedListener((object) this, new Action<List<(ItemRosterElement, int)>, List<(ItemRosterElement, int)>, bool>(this.OnInventoryExchange));
        CampaignEvents.MapEventStarted.AddNonSerializedListener((object) this, new Action<MapEvent, PartyBase, PartyBase>(this.OnMapEventStarted));
      }

      private void OnMapEventStarted(
        MapEvent mapEvent,
        PartyBase attackerParty,
        PartyBase defenderParty)
      {
        if (!QuestHelper.CheckMinorMajorCoercion((QuestBase) this, mapEvent, attackerParty))
          return;
        QuestHelper.ApplyGenericMinorMajorCoercionConsequences((QuestBase) this, mapEvent);
      }

      private void RaidCompleted(BattleSideEnum winnerSide, RaidEventComponent raidEvent)
      {
        if (raidEvent.MapEventSettlement != this.QuestGiver.CurrentSettlement)
          return;
        this.CompleteQuestWithCancel(this.VillageRaidedQuestCancelLog);
      }

      private void OnWarDeclared(
        IFaction faction1,
        IFaction faction2,
        DeclareWarAction.DeclareWarDetail detail)
      {
        QuestHelper.CheckWarDeclarationAndFailOrCancelTheQuest((QuestBase) this, faction1, faction2, detail, this.PlayerDeclaredWarQuestLogText, this.WarDeclaredQuestCancelLog);
      }

      private void OnClanChangedKingdom(
        Clan clan,
        Kingdom oldKingdom,
        Kingdom newKingdom,
        ChangeKingdomAction.ChangeKingdomActionDetail detail,
        bool showNotification = true)
      {
        if (!this.QuestGiver.CurrentSettlement.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          return;
        this.CompleteQuestWithCancel(this.WarDeclaredQuestCancelLog);
      }

      protected override void InitializeQuestOnGameLoad() => this.SetDialogs();

      private void OnInventoryExchange(
        List<(ItemRosterElement, int)> purchasedItems,
        List<(ItemRosterElement, int)> soldItems,
        bool isTrading)
      {
        this.UpdateToolsAmount();
      }

      private int GetCurrentToolsAmountInPlayerRoster()
      {
        return MobileParty.MainParty.ItemRoster.GetItemNumber(this._requestedTradeGood);
      }

      private void UpdateToolsAmount()
      {
        this._numberOfToolsLog.UpdateCurrentProgress((int) MathF.Clamp((float) this.GetCurrentToolsAmountInPlayerRoster(), 0.0f, (float) this._numberOfRequestedGood));
      }

      protected override void OnTimedOut()
      {
        this.AddLog(this.QuestTimeOutFailLog);
        this.QuestGiver.AddPower(-10f);
        this.QuestGiver.CurrentSettlement.Village.Hearth += -30f;
        ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, -5);
      }

      private void FinishQuestSuccess1()
      {
        this.AddLog(this.QuestSuccessLog);
        this.QuestGiver.AddPower(10f);
        TraitLevelingHelper.OnIssueSolvedThroughQuest(Hero.MainHero, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, 30)
        });
        PartyBase.MainParty.ItemRoster.AddToCounts(this._requestedTradeGood, -this._numberOfRequestedGood);
        VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest.GiveTradeOrExchangeRewardToMainParty(this.QuestGiver, this.RewardGold, this._exchangeItem, this._numberOfExchangeItem);
        int num;
        if (this._exchangeItem != null)
        {
          ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, 7);
          foreach (Hero notable in (List<Hero>) this.QuestGiver.CurrentSettlement.Notables)
          {
            if (notable != this.QuestGiver)
              ChangeRelationAction.ApplyPlayerRelation(notable, 2);
          }
          num = 40;
        }
        else
        {
          ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, 5);
          num = 20;
        }
        this.QuestGiver.CurrentSettlement.Village.Hearth += (float) num;
        this.CompleteQuestWithSuccess();
      }

      public static void GiveTradeOrExchangeRewardToMainParty(
        Hero questGiver,
        int gold,
        ItemObject exchangeItem,
        int exchangeItemCount)
      {
        if (exchangeItem != null)
        {
          questGiver.CurrentSettlement.ItemRoster.AddToCounts(exchangeItem, exchangeItemCount);
          ItemRosterElement itemRosterElement = new ItemRosterElement(exchangeItem, exchangeItemCount);
          GiveItemAction.ApplyForParties(questGiver.CurrentSettlement.Party, PartyBase.MainParty, in itemRosterElement);
        }
        else
          GiveGoldAction.ApplyForQuestBetweenCharacters(questGiver, Hero.MainHero, gold);
      }
    }

    public class VillageNeedsToolsIssueTypeDefiner : SaveableTypeDefiner
    {
      public VillageNeedsToolsIssueTypeDefiner()
        : base(600000)
      {
      }

      protected override void DefineClassTypes()
      {
        this.AddClassDefinition(typeof (VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssue), 1);
        this.AddClassDefinition(typeof (VillageNeedsToolsIssueBehavior.VillageNeedsToolsIssueQuest), 2);
      }
    }
  }
}
